﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
using _430GroupProject.Messaging;
using Model.Messaging;
using Model;

namespace _430GroupProject
{
    /// <summary>
    /// This is the service contract used by the android and AST.net.
    /// Any service that would otherwise return void returns an ErrorMessage to indicate if the operation execuated succesfully and if it did not, some details about why.
    /// Most of the other returned object contain an ErrorMessage with a similar meaning, so the state of this ErrorMessage should be checked before using the object.
    /// </summary>
    [ServiceContract]
    public interface IEMSServices
    {
        /// <summary>
        /// Adds the new user to the database.
        /// </summary>
        /// <param name="user">new user to be added to the database.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/addUser",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage addUser(User user);
        
        /// <summary>
        /// Returns the User object corresponding to the given userID.
        /// </summary>
        /// <param name="userID">The userID of the returned user.</param>
        /// <returns>User object corresponding to the given userID.</returns>
        ///         
        [OperationContract(Name="UserByID")]
        [WebInvoke(Method = "POST",
               UriTemplate = "/getUser",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        User getUser(String userID);

        /// <summary>
        /// Gets all the users in the DataBase.
        /// </summary>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/getAllUsers",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        Users getAllUsers();

        /// <summary>
        /// Returns the User that matches the given userName and password, or null if there is no match.
        /// This should be used for logging on.
        /// </summary>
        /// <param name="userID">The userID of the User</param>
        /// <param name="password">The password of the User</param>
        /// <returns>the User that matches the given userName and password, or null if there is no match.</returns>
        [OperationContract] 
	    [WebInvoke(Method = "POST",
        	   UriTemplate = "/getUserLogon",
        	   RequestFormat = WebMessageFormat.Json, 
        	   ResponseFormat = WebMessageFormat.Json)]
        User getUserLogon(String userID, String password);

        /// <summary>
        /// Updates the password for the given user to the given password.
        /// </summary>
        /// <param name="userName">The user whos has changes his/her password</param>
        /// <param name="newPassword">The new password</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/updatePassword",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage updatePassword(String userName, String newPassword);


        /// <summary>
        /// Updates the user with any changes values inside the user object.
        /// This should be used anytime something on a user changes.
        /// </summary>
        /// <param name="user">The user with changes properties.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/updateUser",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage updateUser(User user);

        /// <summary>
        /// Adds a new work session.
        /// This should be used with a user manually creates and enters a completeled work session.
        /// Note: don't use this for updating a clockinsession.
        /// </summary>
        /// <param name="ws"></param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/GetEmployee",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage addWorkSession(WorkSession ws);

        /// <summary>
        /// Retrieves all the users that work in the workgroup with the given workgroup name.
        /// </summary>
        /// <param name="workGroupName">The name of the workgroup to get the users from.</param>
        /// <returns>A Users object containing a list of Users that work in the given workgroup.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/getUsersInWorkGroup",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        Users getUsersInWorkGroup(string workGroupName);

        /// <summary>
        /// Gets a List of the netIDs of all the users in the system.
        /// </summary>
        /// <returns>List of the netIDs of all the users in the system.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/getAllUserNames",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        List<string> getAllUserNames();

        /// <summary>
        /// Updates the worksession with new values.
        /// This should be called after a user clocks in.
        /// </summary>
        /// <param name="ws">The changed worksession object.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/updateWorkSession",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage updateWorkSession(WorkSession ws);

        /// <summary>
        /// Returns all the work groups that the given user is a supervisor for.
        /// </summary>
        /// <param name="userID">The user that is a supervisor of the returned groups.</param>
        /// <returns>WorkGroups that the user is a supervisor for.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/SupervisorFor",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        WorkGroups SupervisorFor(String userID);

        /// <summary>
        /// Returns all the work groups that the given user is an employee of.
        /// </summary>
        /// <param name="userID">The user that is an employee of the return groups.</param>
        /// <returns>WorkGroups that the user is an employee of</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/EmployeeOf",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        WorkGroups EmployeeOf(String userID);


        /// <summary>
        /// Returns the work sessions for a user between the start and end dates (Inclusive).
        /// </summary>
        /// <param name="userID">The user who worked in the sessions.</param>
        /// <param name="start">The beginning of the work period.</param>
        /// <param name="end">The end of the work period.</param>
        /// <returns></returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/userWorkSessions",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        WorkSessions userWorkSessions(String userID, DateTime start, DateTime end);
        
        #region Messaging

        /// <summary>
        /// Sends the given message to the message.to users.
        /// </summary>
        /// <param name="message">The message to be sent.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/sendMessage",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage sendMessage(Message message);

        /// <summary>
        /// Retrieves all message from the given user.
        /// </summary>
        /// <param name="userID">The user to sent the messages.</param>
        /// <returns>A list of messages that the given user has sent.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/getMessagesFrom",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        Messages getMessagesFrom(String userID);


        /// <summary>
        /// Retrieves all messages to the given user.
        /// </summary>
        /// <param name="userID">The user to recived the messages.</param>
        /// <returns>A list of messages that the given user has recieved.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/getMessageTo",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        Messages getMessageTo(String userID);

        /// <summary>
        /// Updates a message in the database when its contents have been changed.
        /// For example if a user reads a message can marks it as read, the message will need to be updated in the DB.
        /// </summary>
        /// <param name="message">The message whos contents have changed.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/updateMessage",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage updateMessage(Message message);
        #endregion

        #region Scheduling
        /// <summary>
        /// Returns the schedule that corresponds to the given name.
        /// </summary>
        /// <param name="scheduleName">The name of the schedule to be returned.</param>
        /// <returns>Schedule that corresponds to the given name.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/getSchedule",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        Schedule getSchedule(String scheduleName);

        /// <summary>
        /// Updates the given schedule in the database with any changes on the object.
        /// </summary>
        /// <param name="changedSchedule">Schedule that has changed.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/updateSchedule",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage updateSchedule(Schedule changedSchedule);

        /// <summary>
        /// Adds the new schedule to the database.
        /// </summary>
        /// <param name="newSchedule">New Schedule to be added to the database.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/addSchedule",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage addSchedule(Schedule newSchedule);
        #endregion

        #region WorkGroups

        /// <summary>
        /// Adds a new workGroup to the database.
        /// </summary>
        /// <param name="newGroup">Adds a new workgroup to the database.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/addWorkGroup",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage addWorkGroup(WorkGroup newGroup);


        /// <summary>
        /// Returns the work group object that corresponds to the given name.
        /// </summary>
        /// <param name="workGroupName">The name of the workgroup to be returned.</param>
        /// <returns>WorkGroup that corresponds to the given name.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/getWorkGroup",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        WorkGroup getWorkGroup(String workGroupName);

        /// <summary>
        /// gets all the workGroups registered, for admin use
        /// </summary>
        /// <returns> all the workGroups registered</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/getAllWorkgroups",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        WorkGroups getAllWorkgroups();

        /// <summary>
        /// Updates the given workgroup with changed values.
        /// </summary>
        /// <param name="toUpdate">The workgroup with changed values.</param>
        /// <returns>The workgroup that was updated</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/updateWorkGroup",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        WorkGroup updateWorkGroup(WorkGroup toUpdate);
        #endregion

        #region TimeSheets

        /// <summary>
        /// Adds a new timesheet to the database.
        /// </summary>
        /// <param name="TS">A new timesheet.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/addTimeSheet",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage addTimeSheet(TimeSheet TS);

        /// <summary>
        /// Retrieves all Open (Not approved by payroll) times
        /// </summary>
        /// <param name="usr">User who sumitted the timesheets.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/getOpenTimeSheets",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        TimeSheets getOpenTimeSheets(User usr);

        /// <summary>
        /// Updates the Timesheet with changed values in the database.
        /// </summary>
        /// <param name="TS">The timesheet with changes values.</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/updateTimeSheet",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage updateTimeSheet(TimeSheet TS);

        /// <summary>
        /// Marks the timesheet as approved by supervisor.
        /// </summary>
        /// <param name="TS">The timesheet to be marked as approved.</param>
        /// <returns>True if the timesheet was updated sucessfully, false otherwise.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/markApprovedBySupervisor",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        bool markApprovedBySupervisor(TimeSheet TS);


        /// <summary>
        /// Marks the timesheet as approved by payroll.
        /// </summary>
        /// <param name="TS">The timesheet to be marked as approved.</param>
        /// <returns>True if the timesheet was updated sucessfully, false otherwise.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/markApprovedByPayroll",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        bool markApprovedByPayroll(TimeSheet TS);


        /// <summary>
        /// Marks the given timesheet as submitted and ready for approval by supervisor.
        /// </summary>
        /// <param name="TS">The timesheet to be submitted</param>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/submitTimeSheet",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage submitTimeSheet(TimeSheet TS);
        #endregion

        /// <summary>
        /// Gets the timeslot with the given IDs from the database.
        /// </summary>
        /// <param name="timeID">The id of the timeslot to retrieve.</param>
        /// <returns>The timeslot corresponding to the given timeslot id.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/addTimeSheet",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        TimeSlot getTimeSlot(Guid timeID);

        /// <summary>
        /// Updates an exsisting Timesheet with the given timesheet object.
        /// </summary>
        /// <param name="updateTs">A changed timesheet to be updated.</param>
        /// <returns>null if no errors occur, or an ErrorMessage containing details about why the operation failed otherwise.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/addTimeSheet",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        ErrorMessage upDateTimeSlot(TimeSlot updateTs);

        /// <summary>
        /// Retrieves a list of all the workgroup names in the system.
        /// </summary>
        /// <returns>list of all the workgroup names in the system.</returns>
        [OperationContract]
        [WebInvoke(Method = "POST",
               UriTemplate = "/addTimeSheet",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
        List<string> getAllWorkgroupNames();
    }
}
